package jp.sourceforge.talisman.csvio;

/*
 * $Id: CsvParser.java,v 1.1 2009/09/12 05:06:12 weiwei Exp $
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import jp.sourceforge.talisman.csvio.builder.CsvLineBuilderFactory;

/**
 * parses csv file.
 * 
 * @author Haruaki Tamada
 * @version $Revision: 1.1 $ $Date: 2009/09/12 05:06:12 $
 */
public class CsvParser implements Iterator<CsvLine>{
    /**
     * reader object represents input stream.
     */
    private BufferedReader in;
    
    /**
     * next line
     */
    private String nextLine;
    
    /**
     * first line unread flag.
     */
    private boolean first = true;

    /**
     * reader object (this object actually parses csv)
     */
    private CsvLineBuilder builder;

    /**
     * Constructor with default settings.
     */
    public CsvParser(BufferedReader in){
        this(in, new CsvIOSetting());
    }

    /**
     * Constructor with given settings.
     */
    public CsvParser(BufferedReader in, CsvIOSetting setting){
        this.in = in;
        builder = CsvLineBuilderFactory.getInstance().createBuilder(setting);
    }

    /**
     * returns parsing setting.
     */
    public CsvIOSetting getSetting(){
        CsvIOSetting setting;
        if(builder == null){
            setting = new CsvIOSetting();
        }
        else{
            setting = builder.getSetting();
        }
        return setting;
    }

    /**
     * sets parsing setting.
     */
    public void setSetting(CsvIOSetting setting){
        builder = CsvLineBuilderFactory.getInstance().createBuilder(setting);
    }

    /**
     * read all lines and returns them.
     */
    public CsvLine[] getAllLines(){
        List<CsvLine> lines = new ArrayList<CsvLine>();
        while(hasNext()){
            lines.add(next());
        }
        return lines.toArray(new CsvLine[lines.size()]);
    }

    /**
     * read a line from file.
     */
    public CsvLine next(){
        if(first){
            getNextLine();
            first = false;
        }
        CsvLine line = null;
        if(nextLine != null){
            line = builder.buildCsvLine(nextLine);
        }
        getNextLine();

        return line;
    }

    /**
     * Is the file reading finished. 
     */
    public boolean hasNext(){
        if(first){
            getNextLine();
            first = false;
        }
        return nextLine != null;
    }

    /**
     * not implemented
     */
    public void remove(){
    }

    /**
     * read next line as string.
     */
    private void getNextLine(){
        try{
            nextLine = in.readLine();
        } catch(IOException e){
        }
    }
}
